/************************ COPYRIGHT INFORMATION **************************** 
 ** This product and related documentation are protected by copyright and 
 ** distributed under licenses restricting its use, copying, distribution, 
 ** and decompilation. No part of this product or related documentation may 
 ** be reproduced in any form by any means without prior written 
 ** authorization of ARGELA TECHNOLOGIES and its licensors, if any. 
 ** Recipient is to retain this program in confidence and is not permitted 
 ** to use or make copies thereof other than as permitted in a written 
 ** agreement with ARGELA TECHNOLOGIES. 
/*************************************************************************** 
 ** Project : TAP 
 ** Module : SERVICE_LOGIC 
 ** File name : LoggerFactory.java 
 ** CM reference : 
 ** Author(s) : cagdasko
 ** Creation Date : Sep 15, 2009 
 ** Description : 
 ** Reference(s) : - (related documents: optional)) 
 *****************************************************************************/

package tr.com.argela.tap.mot.logger;

import java.util.ArrayList;
import java.util.Enumeration;

import org.apache.log4j.FileAppender;
import org.apache.log4j.Logger;
import org.apache.log4j.PropertyConfigurator;
import org.apache.log4j.helpers.FileWatchdog;

/**
 * A helper class for logging operations.
 * 
 * @author cagdasko
 */
public class LoggerFactory {

    private static boolean _isInit = false;

    private static ArrayList<String> loggers;

    /**
     * Initializer method, reads the given path for loading properties from file.
     * 
     * @param path
     */
    private static void printLogger(Logger logger) {
        if (logger == null) {
            return;
        }
        @SuppressWarnings("rawtypes")
        Enumeration e = logger.getAllAppenders();
        while (e.hasMoreElements()) {
            Object obj = e.nextElement();
            if (obj == null) {
                continue;
            }
            if (obj instanceof FileAppender) {
                FileAppender fileAppender = (FileAppender) obj;
                String fileName = (fileAppender.getFile() != null) ? fileAppender.getFile() : "file :-";
                String threshold = (fileAppender.getThreshold() != null) ? fileAppender.getThreshold().toString() : logger.getLevel()
                        .toString();
                String log = "Log4j-> " + fileAppender.getName() + "[" + threshold + "]" + fileName;
                System.out.println(log);
                if (logger.isInfoEnabled()) {
                    logger.info(log);
                }
            }
        }
    }

    private static void printLoggers() {

        if (loggers != null && loggers.size() > 0)
            for (String loggername : loggers) {
                printLogger(getLogger(loggername));
            }
    }

    private static void initLogChangeListener(final String path) {
        FileWatchdog fileWatchdog = new FileWatchdog(path) {

            @Override
            protected void doOnChange() {
                System.out.println("Log4j -> File Changed , log4j init again ," + path);
                PropertyConfigurator.configure(path);
                if (_isInit) {
                    printLoggers();
                }
            }
        };
        fileWatchdog.start();
    }

    /**
     * @param path
     * @param defaultAppender
     */
    public static void init(final String path, String defaultAppender, ArrayList<String> loggers) {
        if (!_isInit) {
            try {
                System.out.println("Log4j ->[BEGIN]  Init from path : " + path);
                PropertyConfigurator.configure(path);
                System.out.println("Log4j ->[SUCCESS] Init from path : " + path);
                _isInit = true;
            } catch (Exception e) {
                System.out.println("Log4j ->[FAILED] Init from path : " + path);
                e.printStackTrace();
            }

            Logger out = getLogger(defaultAppender);
            out.info("Logger initialized from path: " + path);

            LoggerFactory.setLoggers(loggers);

            printLoggers();

            initLogChangeListener(path);
        }
    }

    /**
     * Returns a logger with specified name in log4j.properties. If the method called without initializing the class, a default property
     * file location is used as "properties/log4.properties".
     * 
     * @param name
     * @return
     */
    public static Logger getLogger(String name) {
        return Logger.getLogger(name);
    }

    /**
     * Returns a logger with specified name in log4j.properties. If the method called without initializing the class, a default property
     * file location is used as "properties/log4.properties".
     * 
     * @param name
     * @return
     */
    public static Logger getLogger(Class _class) {
        return Logger.getLogger(_class);
    }

    /**
     * @return the loggers
     */
    public static ArrayList<String> getLoggers() {
        return loggers;
    }

    /**
     * @param loggers
     *            the loggers to set
     */
    public static void setLoggers(ArrayList<String> loggers) {
        LoggerFactory.loggers = loggers;
    }
}
